#!/user/bin/env python3
# -*- coding: utf-8 -*-
import os
import glob
import shutil
from win32com import client as wc
from docx import Document
from bs4 import BeautifulSoup
import base64
from docx.document import Document as _Document
from docx.oxml.table import CT_Tbl
from docx.oxml.text.paragraph import CT_P
from docx.table import Table
from docx.text.paragraph import Paragraph


def clear_folder(folder_path):
    """清空指定文件夹中的所有文件"""
    if os.path.exists(folder_path):
        for filename in os.listdir(folder_path):
            file_path = os.path.join(folder_path, filename)
            try:
                if os.path.isfile(file_path) or os.path.islink(file_path):
                    os.unlink(file_path)
                elif os.path.isdir(file_path):
                    shutil.rmtree(file_path)
            except Exception as e:
                print(f'删除 {file_path} 时出错: {e}')
        print(f'已清空文件夹: {folder_path}')

def doc_to_docx(doc_path, docx_path):
    """将 .doc 转换为 .docx（仅Windows）"""
    word = wc.Dispatch("Word.Application.16")
    doc = word.Documents.Open(doc_path)
    doc.SaveAs(docx_path, 12)  # 12 表示 .docx 格式
    doc.Close()
    word.Quit()


def clean_text_json(text):
    return text.replace(',', ' ').strip()


def clean_text(text):
    text = text.replace(' ', '').strip()
    return text.replace('\n', '').strip()


def process_table(table):
    # 获取表格的行数和列数
    row_count = len(table.rows)
    col_count = max(len(row.cells) for row in table.rows)

    # 初始化表格数据结构
    table_data = {
        "row_count": row_count,
        "col_count": col_count,
        "data": []
    }

    # 填充表格数据
    for row in table.rows:
        row_data = []
        for cell in row.cells:
            # 清理单元格文本中的换行符
            cleaned_text = clean_text(cell.text)
            row_data.append(cleaned_text)
        # 补齐列数
        while len(row_data) < col_count:
            row_data.append("")
        table_data["data"].append(row_data)

    return table_data


def remove_smart_tags(doc):
    # 定义智能标记的命名空间
    nsmap = {
        'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
        'st': 'http://schemas.microsoft.com/office/word/2003/wordml/sp2'
    }

    # 遍历文档所有XML元素
    for element in doc.element.xpath('//*[contains(name(), "smartTag")]'):
        parent = element.getparent()
        # 保留智能标记内的内容
        for child in element.iterchildren():
            parent.insert(parent.index(element), child)
        parent.remove(element)

    return doc


def iter_block_items(parent):
    if isinstance(parent, _Document):
        parent_elm = parent.element.body
    else:
        raise ValueError("必须是 Document 对象")
    for child in parent_elm:
        # 正常处理段落和表格
        if isinstance(child, CT_P):
            yield Paragraph(child, parent)
        elif isinstance(child, CT_Tbl):
            yield Table(child, parent)


def docx_to_html_with_images(docx_path, output_html_path):
    doc = Document(docx_path)
    doc = remove_smart_tags(doc)
    soup = BeautifulSoup('<html><head><meta charset="UTF-8"></head><body></body></html>', 'html.parser')
    body = soup.body

    for block in iter_block_items(doc):
        if isinstance(block, Paragraph):
            # 清理段落文本中的换行符
            cleaned_text = clean_text(block.text)
            if block.style.name == "Heading 1":
                h1 = soup.new_tag('h1')
                h1.string = "*** " + cleaned_text
                body.append(h1)
            elif block.style.name == "Heading 2":
                h2 = soup.new_tag('h2')
                h2.string = "!!! " + cleaned_text
                body.append(h2)
            else:
                p = soup.new_tag('p')
                p.string = cleaned_text
                body.append(p)
        elif isinstance(block, Table):
            # 处理表格并转换为JSON
            table_json = process_table(block)
            json_str = "row_count:{}, col_count:{}\n".format(table_json["row_count"], table_json["col_count"])
            for i in range(table_json["row_count"]):
                for j in range(table_json["col_count"]):
                    json_str = json_str + table_json["data"][i][j] + " | "
                json_str = json_str[:-1]
                json_str = json_str + "\n"
            # json_str = json.dumps(table_json, ensure_ascii=False, indent=2)
            json_str = clean_text_json(json_str)

            # 创建pre标签显示JSON
            pre = soup.new_tag('pre')
            pre.string = json_str
            body.append(pre)

            # 表格结束标记
            table_end = soup.new_tag('p')
            table_end.string = "!!!"
            body.append(table_end)

    # 图片处理
    for rel in doc.part.rels.values():
        if "image" in rel.target_ref:
            image_part = rel.target_part
            image_data = image_part.blob
            base64_data = base64.b64encode(image_data).decode('utf-8')

            content_type = image_part.content_type
            image_format = content_type.split("/")[-1]
            if image_format == "jpeg":
                image_format = "jpg"

            img_tag = soup.new_tag('img',
                                   src=f"data:image/{image_format};base64,{base64_data}",
                                   style="max-width:50%")
            body.append(img_tag)

    with open(output_html_path, 'w', encoding='utf-8') as f:
        f.write(str(soup))


# 批量处理word文件夹中的所有doc和docx文件
word_folder = 'word'
html_folder = 'html'

# 清空html输出文件夹
clear_folder(html_folder)

# 创建html输出文件夹
if not os.path.exists(html_folder):
    os.makedirs(html_folder)

# 获取所有doc和docx文件
doc_files = glob.glob(os.path.join(word_folder, '*.doc'))
docx_files = glob.glob(os.path.join(word_folder, '*.docx'))

# 处理doc文件
for doc_path in doc_files:
    filename = os.path.splitext(os.path.basename(doc_path))[0]
    temp_docx_path = f'temp_{filename}.docx'
    output_html_path = os.path.join(html_folder, f'{filename}.html')
    
    # print(f'正在处理: {doc_path}')
    # doc转docx再转html
    doc_to_docx(os.path.abspath(doc_path), os.path.abspath(temp_docx_path))
    docx_to_html_with_images(temp_docx_path, output_html_path)
    # 删除临时docx文件
    os.remove(temp_docx_path)
    print(f' {output_html_path}')

# 处理docx文件
for docx_path in docx_files:
    filename = os.path.splitext(os.path.basename(docx_path))[0]
    output_html_path = os.path.join(html_folder, f'{filename}.html')

    # print(f'正在处理: {docx_path}')
    # 直接转html
    docx_to_html_with_images(docx_path, output_html_path)
    print(f' {output_html_path}')

print('所有word文件处理为html格式')